/* control.cpp
Michael Zahniser, 12/12/09

Function definitions for the control operators.
*/

#include "Operators.h"

using std::string;


namespace {
	string Clear = "clear ^n";
	static const Do<Clear> clear;

	string Reset = "reset";
	static const Do<Reset> reset;

	string Swap = "swap ^s";
	static const Do<Swap> swap;

	string Duplicate = "duplicate dup ^d";
	static const Do<Duplicate> duplicate;

	string Define = "define def =";
	static const Do<Define> define;

	string Function = "function fun {";
	static const Do<Function> function;

	string SkipIf = "skipif if";
	static const Do<SkipIf> skipif;
	
	string StackSize = "stacksize stack #";
	static const Do<StackSize> stacksize;
	
	string Binary = "binary bin";
	static const Do<Binary> binary;
	
	string Octal = "octal oct";
	static const Do<Octal> octal;
	
	string Decimal = "decimal dec";
	static const Do<Decimal> decimal;
	
	string Hexadecimal = "hexadecimal hex";
	static const Do<Hexadecimal> hexadecimal;
	
	string Degrees = "degrees deg";
	static const Do<Degrees> degrees;
	
	string Radians = "radians rad";
	static const Do<Radians> radians;
}



template <> void Do<Clear>::operator()(State &state) const
{
	state.Clear();
}



template <> void Do<Reset>::operator()(State &state) const
{
	state.Reset();
}



template <> void Do<Swap>::operator()(State &state) const
{
	double b = state.Pop();
	double a = state.Pop();
	state.Push(b);
	state.Push(a);
}



template <> void Do<Duplicate>::operator()(State &state) const
{
	state.Push(state.Stack().back());
}



template <> void Do<Define>::operator()(State &state) const
{
	state.SetMode(State::DEFINING);
}



template <> void Do<Function>::operator()(State &state) const
{
	state.SetMode(State::PROGRAMMING);
}



template <> void Do<SkipIf>::operator()(State &state) const
{
	if(!state.Pop())
		state.SetMode(State::SKIPPING);
}



template <> void Do<StackSize>::operator()(State &state) const
{
	state.Push(state.Stack().size());
}



template <> void Do<Binary>::operator()(State &state) const
{
	state.SetBase(2);
}



template <> void Do<Octal>::operator()(State &state) const
{
	state.SetBase(8);
}



template <> void Do<Decimal>::operator()(State &state) const
{
	state.SetBase(10);
}



template <> void Do<Hexadecimal>::operator()(State &state) const
{
	state.SetBase(16);
}



template <> void Do<Degrees>::operator()(State &state) const
{
	state.SetAngle(State::DEGREES);
}



template <> void Do<Radians>::operator()(State &state) const
{
	state.SetAngle(State::RADIANS);
}
